/**
 * This class represents a TW unit.
 */
function Unit(id, name, speed) {
    /**
     * Unit id (used on in-game forms).
     */
    this.id = id;
    
    /**
     * Unit name.
     */
    this.name = name;
    
    /**
     * Unit speed (minutes needed to pass 1 square).
     */
    this.speed = speed;
}

/**
 * This class represents a pair of coordinates.
 */
function Coords(xcoord, ycoord) {
    /**
     * X coordinate.
     */
    this.x = xcoord;

    /**
     * Y coordinate.
     */
    this.y = ycoord;
    
    /**
     * Get the distance between this and another pair of coordinates.
     *
     * @param otherCoords the other coordinate pair
     * @return the distance
     */
    this.getDistance = function(otherCoords) {
        var xDiff = this.x - otherCoords.x;
        var yDiff = this.y - otherCoords.y;
        return Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2));
    }
}

/**
 * This class encompasses static utility functions.
 */
function TTW() {
    /**
     * Spear unit.
     */
    this.spear = new Unit('spear', 'Spear', 18);

    /**
     * Sword unit.
     */
    this.sword = new Unit('sword', 'Sword', 22);

    /**
     * Axe unit.
     */
    this.axe = new Unit('axe', 'Axe', 18);

    /**
     * Spear unit.
     */
    this.archer = new Unit('archer', 'Archer', 18);

    /**
     * Scout unit.
     */
    this.scout = new Unit('spy', 'Scout', 9);

    /**
     * LC unit.
     */
    this.lc = new Unit('light', 'Light Cavalry', 10);

    /**
     * MA unit.
     */
    this.ma = new Unit('marcher', 'Mounted Archer', 10);

    /**
     * HC unit.
     */
    this.hc = new Unit('heavy', 'Heavy Cavalry', 11);

    /**
     * Ram unit.
     */
    this.ram = new Unit('ram', 'Ram', 30);

    /**
     * Cat unit.
     */
    this.cat = new Unit('catapult', 'Catapult', 30);

    /**
     * Paladin unit.
     */
    this.paladin = new Unit('knight', 'Paladin', 10);

    /**
     * Noble unit.
     */
    this.noble = new Unit('snob', 'Noble', 35);

    /**
     * An array enumerating the unit types.
     */
    this.units = new Array();
    this.units[this.units.length] = this.spear;
    this.units[this.units.length] = this.sword;
    this.units[this.units.length] = this.axe;
    this.units[this.units.length] = this.archer;
    this.units[this.units.length] = this.scout;
    this.units[this.units.length] = this.lc;
    this.units[this.units.length] = this.ma;
    this.units[this.units.length] = this.hc;
    this.units[this.units.length] = this.ram;
    this.units[this.units.length] = this.cat;
    this.units[this.units.length] = this.paladin;
    this.units[this.units.length] = this.noble;

    /**
     * Get the first coordinate pair from a given text.
     *
     * @param text the text to extract the coordinates from
     * @return a Coords object containin the coordinates
     */
    this.getCoords = function(text) {
        var coordString = text.match(/\d{1,3}\|\d{1,3}/)[0];
        
        var coords = {
            x: parseInt(coordString.split('|')[0]),
            y: parseInt(coordString.split('|')[1])
        }
        
        return new Coords(coords.x, coords.y);
    };
    
    /**
     * Get the distance between the first coordinate pair in the first text
     * and the first coordinate par from the second text.
     * 
     * @param text1 text containing the first coordinate pair
     * @param text2 text containing the second coordinate pair
     * @return the distance between the two coordinate pairs
     */
    this.getDistance = function(text1, text2) {
        var coords1 = this.getCoords(text1);
        var coords2 = this.getCoords(text2);
        
        return coords1.getDistance(coords2);
    };
    
    /**
     * Get the travel time (in minutes) by the specified unit between two
     * coordinates gathered from the specified texts.
     * 
     * @param text1 text containing the first coordinate pair
     * @param text2 text containing the second coordinate pair
     * @param unit the unit to measure the travel time for
     * @return the calculated travel time in minutes
     */
    this.getTravelTime = function(text1, text2, unit) {
        var distance = ttw.getDistance(text1, text2);
        
        return distance * unit.speed;
    };
    
    /**
     * Load an external module from the specified source location.
     *
     * @param src the location of the module source
     */
    this.loadModule = function(src) {
        var script = document.createElement('script');
        
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('src', src);
        
        var scriptContent = document.createTextNode(' ');
        script.appendChild(scriptContent);
        
        document.getElementsByTagName('body')[0].appendChild(script);
    }
}

var ttw = new TTW();
